using System;
using System.Collections;
using System.Collections.Generic;
using SkaldRogueLike.Main.CellContent.Items;

namespace SkaldRogueLike.Main.Common
{
    public class SortedListOfItems : IList<Item>
    {
        public const int Capacity = 26;
        protected readonly List<Item> List;

        public SortedListOfItems()
        {
            List = new List<Item>(Capacity);
        }

        public SortedListOfItems(IEnumerable<Item> items)
        {
            List = new List<Item>(Capacity);
            List.AddRange(items);
            Resort();
        }

        protected void Resort()
        {
            List.Sort((a, b) => 
                {
                    var result = 0;
                    if (a is Equipment)
                        if (b is Equipment)
                            result = (a as Equipment).PlaceType.CompareTo((b as Equipment).PlaceType);
                        else
                            return -1;
                    else
                        if (b is Equipment)
                            return 1;
                    result = result != 0 ? result : a.BonusType.CompareTo(b.BonusType);
                    return result != 0 ? result : String.Compare(a.Name, b.Name, StringComparison.Ordinal);
                });
        }

        public void AddRange(IEnumerable<Item> range)
        {
            List.AddRange(range);
            Resort();
        }

        #region Implementation of IEnumerable

        public IEnumerator<Item> GetEnumerator()
        {
            return List.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        #region Implementation of ICollection<Item>

        public void Add(Item item)
        {
            List.Add(item);
            Resort();
        }

        public void Clear()
        {
            List.Clear();
        }

        public bool Contains(Item item)
        {
            return List.Contains(item);
        }

        public void CopyTo(Item[] array, int arrayIndex)
        {
            List.CopyTo(array, arrayIndex);
        }

        public bool Remove(Item item)
        {
            var result = List.Remove(item);
            Resort();
            return result;
        }

        public int Count { get { return List.Count; } }
        public bool IsReadOnly { get { return false; } }

        #endregion

        #region Implementation of IList<Item>

        public int IndexOf(Item item)
        {
            return List.IndexOf(item);
        }

        public void Insert(int index, Item item)
        {
            throw new NotSupportedException("You can not insert items into sorted list by index!");
        }

        public void RemoveAt(int index)
        {
            List.RemoveAt(index);
            Resort();
        }

        public Item this[int index]
        {
            get
            {
                return List[index];
            }
            set
            {
                List[index] = value;
                Resort();
            }
        }

        #endregion
    }
}